# -*- coding: utf-8 -*- 
#
# Description:
#
#  Definiton
#
#
#
# Changes:
#
# 2012-01-10
# Initial Commit
#
#
# Copyright 2010-2012, WyDev Team.
# Author: Polo35 (polo35580@hotmail.fr)
#
# Licenced under Academic Free License version 3.0
# Review WyGui README & LICENSE files for further details.

nname: 151
n 151(None)[return ast_list
]:
	i: 56(AL), 150()
	o: 

nname: 150
n 150(None)[]:
	i: 69(AF), 146()
	o: 151()

nname: 146
n 146(None)[]:
	i: 111(f), 126()
	o: 150()

nname: 126
n 126(None)[ast_list[index] = annotate_ast_list(item)
continue
]:
	i: 111(t)
	o: 146()

nname: 111
n 111(isinstance(item, list))[]:
	i: 103(), 110()
	o: 126(t), 146(f)

nname: 110
n 110(None)[]:
	i: 82(f)
	o: 111()

nname: 103
n 103(None)[continue
]:
	i: 82(t)
	o: 111()

nname: 82
n 82(index == 0)[for index, item in enumerate(ast_list):
]:
	i: 69(for)
	o: 103(t), 110(f)

nname: 69
n 69(None)[]:
	i: 56(loop)
	o: 82(for), 150(AF)

nname: 56
n 56(None)[ast_list[0] = code
]:
	i: 25(), 42()
	o: 69(loop), 151(AL)

nname: 42
n 42(None)[code = token.tok_name[code]
]:
	i: 0(f)
	o: 56()

nname: 25
n 25(None)[code = symbol.sym_name[code]
]:
	i: 0(t)
	o: 56()

nname: 0
n 0(code in symbol.sym_name)[code = ast_list[0]
]:
	i: 
	o: 25(t), 42(f)

nname: 151
n 151(None)[return ast_list
]:
	i: 0(AL), 69(AF), 82(f)
	o: 

nname: 82
n 82(None)[for index, item in enumerate(ast_list):
if index == 0:
	continue
if isinstance(item, list):
	ast_list[index] = annotate_ast_list(item)
	continue
]:
	i: 69(for)
	o: 151()

nname: 69
n 69(None)[]:
	i: 0(loop)
	o: 82(for), 151(AF)

nname: 0
n 0(None)[code = ast_list[0]
if code in symbol.sym_name:
	code = symbol.sym_name[code]
else:
	code = token.tok_name[code]
ast_list[0] = code
]:
	i: 
	o: 69(loop), 151(AL)

self.nodes: {0: <unpyclib.structure.node instance at 0xb7604f0c>, 69: <unpyclib.structure.node instance at 0xb7604d6c>, 82: <unpyclib.structure.node instance at 0xb7604fac>, 151: <unpyclib.structure.node instance at 0xb760b30c>}
nname: 44
n 44(None)[return first_child[1]
]:
	i: 35(), 43()
	o: 

nname: 43
n 43(None)[]:
	i: 0(f)
	o: 44()

nname: 35
n 35(None)[return None
]:
	i: 0(t)
	o: 44()

nname: 0
n 0(first_child_code != token.NAME)[first_child = atom[1]
first_child_code = first_child[0]
]:
	i: 
	o: 35(t), 43(f)

nname: 0
n 0(None)[first_child = atom[1]
first_child_code = first_child[0]
if first_child_code != token.NAME:
	return None
return first_child[1]
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xb760408c>}
nname: 213
n 213(None)[return None
]:
	i: 200(), 208()
	o: 

nname: 208
n 208(None)[return None
]:
	i: 153&176(f)
	o: 213()

nname: 200
n 200(None)[return fn_name
]:
	i: 153&176(t)
	o: 213()

nname: 153&176
n 153&176(second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR)[]:
	i: 144(), 152()
	o: 200(t), 208(f)

nname: 152
n 152(None)[]:
	i: 126(f)
	o: 153&176()

nname: 144
n 144(None)[return None
]:
	i: 126(t)
	o: 153&176()

nname: 126
n 126(len(second_child) < 3)[]:
	i: 117(), 125()
	o: 144(t), 152(f)

nname: 125
n 125(None)[]:
	i: 80(f)
	o: 126()

nname: 117
n 117(None)[return None
]:
	i: 80(t)
	o: 126()

nname: 80
n 80(second_child_code != symbol.trailer)[fn_name = get_atom_name(first_child)
second_child_code = second_child[0]
]:
	i: 71(), 79()
	o: 117(t), 125(f)

nname: 79
n 79(None)[]:
	i: 27(f)
	o: 80()

nname: 71
n 71(None)[return None
]:
	i: 27(t)
	o: 80()

nname: 27
n 27(first_child_code != symbol.atom)[first_child, second_child = ast_list[1:3]
first_child_code = first_child[0]
]:
	i: 18(), 26()
	o: 71(t), 79(f)

nname: 26
n 26(None)[]:
	i: 0(f)
	o: 27()

nname: 18
n 18(None)[return None
]:
	i: 0(t)
	o: 27()

nname: 0
n 0(len(ast_list) < 3)[]:
	i: 
	o: 18(t), 26(f)

nname: 153&176
n 153&176(None)[if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
	return fn_name
else:
	return None
return None
]:
	i: 80()
	o: 

nname: 80
n 80(None)[fn_name = get_atom_name(first_child)
second_child_code = second_child[0]
if second_child_code != symbol.trailer:
	return None
if len(second_child) < 3:
	return None
]:
	i: 0()
	o: 153&176()

nname: 0
n 0(None)[if len(ast_list) < 3:
	return None
first_child, second_child = ast_list[1:3]
first_child_code = first_child[0]
if first_child_code != symbol.atom:
	return None
]:
	i: 
	o: 80()

nname: 153&176
n 153&176(None)[if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
	return fn_name
else:
	return None
return None
]:
	i: 0()
	o: 

nname: 0
n 0(None)[if len(ast_list) < 3:
	return None
first_child, second_child = ast_list[1:3]
first_child_code = first_child[0]
if first_child_code != symbol.atom:
	return None
fn_name = get_atom_name(first_child)
second_child_code = second_child[0]
if second_child_code != symbol.trailer:
	return None
if len(second_child) < 3:
	return None
]:
	i: 
	o: 153&176()

nname: 0
n 0(None)[if len(ast_list) < 3:
	return None
first_child, second_child = ast_list[1:3]
first_child_code = first_child[0]
if first_child_code != symbol.atom:
	return None
fn_name = get_atom_name(first_child)
second_child_code = second_child[0]
if second_child_code != symbol.trailer:
	return None
if len(second_child) < 3:
	return None
if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
	return fn_name
else:
	return None
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xb760be8c>}
nname: 151
n 151(None)[return None
]:
	i: 97(AL), 150()
	o: 

nname: 150
n 150(None)[]:
	i: 100(AF), 146()
	o: 151()

nname: 146
n 146(None)[]:
	i: 111(f), 129()
	o: 150()

nname: 129
n 129(None)[find_fn_call(item, calls)
continue
]:
	i: 111(t)
	o: 146()

nname: 111
n 111(isinstance(item, list))[for item in ast_list[1:]:
]:
	i: 100(for)
	o: 129(t), 146(f)

nname: 100
n 100(None)[]:
	i: 97(loop)
	o: 111(for), 150(AF)

nname: 97
n 97(None)[]:
	i: 75(JA), 92(), 96()
	o: 100(loop), 151(AL)

nname: 96
n 96(None)[]:
	i: 0(f)
	o: 97()

nname: 92
n 92(None)[]:
	i: 25&50(f)
	o: 97()

nname: 75
n 75(None)[calls.add(fn_name)
]:
	i: 25&50(t)
	o: 97(JA)

nname: 25&50
n 25&50(fn_name != None and getattr(__builtins__, fn_name, None) == None)[fn_name = get_fn_call_data(ast_list)
]:
	i: 0(t)
	o: 75(t), 92(f)

nname: 0
n 0(code == symbol.power)[code = ast_list[0]
]:
	i: 
	o: 25&50(t), 96(f)

nname: 151
n 151(None)[return None
]:
	i: 0(AL), 100(AF), 111()
	o: 

nname: 111
n 111(None)[for item in ast_list[1:]:
if isinstance(item, list):
	find_fn_call(item, calls)
	continue
]:
	i: 100(for)
	o: 151()

nname: 100
n 100(None)[]:
	i: 0(loop)
	o: 111(for), 151(AF)

nname: 0
n 0(None)[code = ast_list[0]
if code == symbol.power:
	fn_name = get_fn_call_data(ast_list)
	if fn_name != None and getattr(__builtins__, fn_name, None) == None:
		calls.add(fn_name)
]:
	i: 
	o: 100(loop), 151(AL)

self.nodes: {0: <unpyclib.structure.node instance at 0xb7604cac>, 100: <unpyclib.structure.node instance at 0xb760474c>, 111: <unpyclib.structure.node instance at 0xb7604f8c>, 151: <unpyclib.structure.node instance at 0xb760b44c>}
nname: 0
n 0(None)[dummy, dummy, func_name = fn_ast_list[:3]
dummy, func_name = func_name
calls = set()
find_fn_call(fn_ast_list, calls)
call_graph[func_name] = list(calls)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xb760482c>}
nname: 97
n 97(None)[return call_graph
]:
	i: 43(AL), 96()
	o: 

nname: 96
n 96(None)[]:
	i: 46(AF), 92()
	o: 97()

nname: 92
n 92(None)[]:
	i: 57(f), 75()
	o: 96()

nname: 75
n 75(None)[construct_call_graph(item, call_graph)
continue
]:
	i: 57(t)
	o: 92()

nname: 57
n 57(isinstance(item, list))[for item in ast_list[1:]:
]:
	i: 46(for)
	o: 75(t), 92(f)

nname: 46
n 46(None)[]:
	i: 43(loop)
	o: 57(for), 96(AF)

nname: 43
n 43(None)[]:
	i: 25(), 42()
	o: 46(loop), 97(AL)

nname: 42
n 42(None)[]:
	i: 0(f)
	o: 43()

nname: 25
n 25(None)[process_fn(ast_list, call_graph)
]:
	i: 0(t)
	o: 43()

nname: 0
n 0(code == symbol.funcdef)[code = ast_list[0]
]:
	i: 
	o: 25(t), 42(f)

nname: 97
n 97(None)[return call_graph
]:
	i: 0(AL), 46(AF), 57()
	o: 

nname: 57
n 57(None)[for item in ast_list[1:]:
if isinstance(item, list):
	construct_call_graph(item, call_graph)
	continue
]:
	i: 46(for)
	o: 97()

nname: 46
n 46(None)[]:
	i: 0(loop)
	o: 57(for), 97(AF)

nname: 0
n 0(None)[code = ast_list[0]
if code == symbol.funcdef:
	process_fn(ast_list, call_graph)
]:
	i: 
	o: 46(loop), 97(AL)

self.nodes: {0: <unpyclib.structure.node instance at 0xb7604e4c>, 97: <unpyclib.structure.node instance at 0xb7604d0c>, 46: <unpyclib.structure.node instance at 0xb76047cc>, 57: <unpyclib.structure.node instance at 0xb7604ecc>}
nname: 198
n 198(None)[dot.append('}')
return '\n'.join(dot)
]:
	i: 0(AL), 197()
	o: 

nname: 197
n 197(None)[]:
	i: 84(AF), 194()
	o: 198()

nname: 194
n 194(None)[]:
	i: 134(AL), 193()
	o: 197()

nname: 193
n 193(None)[]:
	i: 137(AF), 167()
	o: 194()

nname: 167
n 167(None)[dot.append('%s -> %s;' % (from_fn, to_fn))
]:
	i: 159(), 166()
	o: 193()

nname: 166
n 166(None)[]:
	i: 144(f)
	o: 167()

nname: 159
n 159(None)[continue
]:
	i: 144(t)
	o: 167()

nname: 144
n 144(to_fn not in call_graph)[for to_fn in to_fns:
]:
	i: 137(for)
	o: 159(t), 166(f)

nname: 137
n 137(None)[]:
	i: 134(loop)
	o: 144(for), 193(AF)

nname: 134
n 134(None)[]:
	i: 112(), 133()
	o: 137(loop), 194(AL)

nname: 133
n 133(None)[]:
	i: 97(t)
	o: 134()

nname: 112
n 112(None)[dot.append('%s;' % from_fn)
]:
	i: 97(f)
	o: 134()

nname: 97
n 97(to_fns)[for from_fn, to_fns in call_graph.iteritems():
]:
	i: 84(for)
	o: 112(f), 133(t)

nname: 84
n 84(None)[]:
	i: 0(loop)
	o: 97(for), 197(AF)

nname: 0
n 0(None)[ast = parser.suite(python_code)
ast_list = parser.ast2list(ast)
call_graph = {}
construct_call_graph(ast_list, call_graph)
dot = []
dot.append('digraph G {')
dot.append('rankdir=LR')
]:
	i: 
	o: 84(loop), 198(AL)

nname: 198
n 198(None)[dot.append('}')
return '\n'.join(dot)
]:
	i: 0(AL), 84(AF), 97(AL), 137(AF), 144()
	o: 

nname: 144
n 144(None)[for to_fn in to_fns:
if to_fn not in call_graph:
	continue
dot.append('%s -> %s;' % (from_fn, to_fn))
]:
	i: 137(for)
	o: 198()

nname: 137
n 137(None)[]:
	i: 97(loop)
	o: 144(for), 198(AF)

nname: 97
n 97(None)[for from_fn, to_fns in call_graph.iteritems():
if not to_fns:
	dot.append('%s;' % from_fn)
]:
	i: 84(for)
	o: 137(loop), 198(AL)

nname: 84
n 84(None)[]:
	i: 0(loop)
	o: 97(for), 198(AF)

nname: 0
n 0(None)[ast = parser.suite(python_code)
ast_list = parser.ast2list(ast)
call_graph = {}
construct_call_graph(ast_list, call_graph)
dot = []
dot.append('digraph G {')
dot.append('rankdir=LR')
]:
	i: 
	o: 84(loop), 198(AL)

self.nodes: {0: <unpyclib.structure.node instance at 0xb760b58c>, 97: <unpyclib.structure.node instance at 0xb760b14c>, 137: <unpyclib.structure.node instance at 0xb760b94c>, 144: <unpyclib.structure.node instance at 0xb760bd4c>, 198: <unpyclib.structure.node instance at 0xb760b46c>, 84: <unpyclib.structure.node instance at 0xb760b60c>}
nname: 333
n 333(None)[]:
	i: 312(), 332()
	o: 

nname: 332
n 332(None)[]:
	i: 122(f)
	o: 333()

nname: 312
n 312(None)[dot_code = generate_dot_code(python_code)
print dot_code
]:
	i: 271(), 296()
	o: 333()

nname: 296
n 296(None)[python_code = sys.stdin.read()
]:
	i: 197(f)
	o: 312()

nname: 271
n 271(None)[python_code = open(options.input_file).read()
]:
	i: 197(t)
	o: 312()

nname: 197
n 197(options.input_file)[oparser = optparse.OptionParser()
oparser.add_option('-i', '--input-file', default=None, metavar='FILE', help='python code file to process')
options, args = oparser.parse_args()
]:
	i: 122(t)
	o: 271(t), 296(f)

nname: 122
n 122(__name__ == '__main__')[def annotate_ast_list(ast_list):
	code = ast_list[0]
	if code in symbol.sym_name:
		code = symbol.sym_name[code]
	else:
		code = token.tok_name[code]
	ast_list[0] = code

def get_atom_name(atom):
	first_child = atom[1]
	first_child_code = first_child[0]
	if first_child_code != token.NAME:
		return None
	return first_child[1]

def get_fn_call_data(ast_list):
	if len(ast_list) < 3:
		return None
	first_child, second_child = ast_list[1:3]
	first_child_code = first_child[0]
	if first_child_code != symbol.atom:
		return None
	fn_name = get_atom_name(first_child)
	second_child_code = second_child[0]
	if second_child_code != symbol.trailer:
		return None
	if len(second_child) < 3:
		return None
	if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
		return fn_name
	else:
		return None
	return None

def find_fn_call(ast_list, calls):
	code = ast_list[0]
	if code == symbol.power:
		fn_name = get_fn_call_data(ast_list)
		if fn_name != None and getattr(__builtins__, fn_name, None) == None:
			calls.add(fn_name)

def process_fn(fn_ast_list, call_graph):
	dummy, dummy, func_name = fn_ast_list[:3]
	dummy, func_name = func_name
	calls = set()
	find_fn_call(fn_ast_list, calls)
	call_graph[func_name] = list(calls)

def construct_call_graph(ast_list, call_graph):
	code = ast_list[0]
	if code == symbol.funcdef:
		process_fn(ast_list, call_graph)

def generate_dot_code(python_code):
	ast = parser.suite(python_code)
	ast_list = parser.ast2list(ast)
	call_graph = {}
	construct_call_graph(ast_list, call_graph)
	dot = []
	dot.append('digraph G {')
	dot.append('rankdir=LR')

]:
	i: 81(), 94(), 121(AE)
	o: 197(t), 332(f)

nname: 94
n 94(None)[import sets
set = sets.Set
]:
	i: 0(except)
	o: 122()

nname: 81
n 81(None)[s = set()
]:
	i: 0(try)
	o: 122()

nname: 0
n 0(None)[__doc__ = '\ngenerates call graph of given python code file\nin dot format input for graphviz.\n\nlimitations:\n* statically tried to figure out functions calls\n* does not understand classes\n* algorithm is naive and may not statically find\n  all cases\n'
import sys
import parser
import symbol
import token
import pprint
import optparse
]:
	i: 
	o: 81(try), 94(except)

nname: 333
n 333(None)[]:
	i: 197(), 94(f)
	o: 

nname: 197
n 197(None)[oparser = optparse.OptionParser()
oparser.add_option('-i', '--input-file', default=None, metavar='FILE', help='python code file to process')
options, args = oparser.parse_args()
if options.input_file:
	python_code = open(options.input_file).read()
else:
	python_code = sys.stdin.read()
dot_code = generate_dot_code(python_code)
print dot_code
]:
	i: 94(t)
	o: 333()

nname: 94
n 94(__name__ == '__main__')[except:
	import sets
	set = sets.Set
def annotate_ast_list(ast_list):
	code = ast_list[0]
	if code in symbol.sym_name:
		code = symbol.sym_name[code]
	else:
		code = token.tok_name[code]
	ast_list[0] = code

def get_atom_name(atom):
	first_child = atom[1]
	first_child_code = first_child[0]
	if first_child_code != token.NAME:
		return None
	return first_child[1]

def get_fn_call_data(ast_list):
	if len(ast_list) < 3:
		return None
	first_child, second_child = ast_list[1:3]
	first_child_code = first_child[0]
	if first_child_code != symbol.atom:
		return None
	fn_name = get_atom_name(first_child)
	second_child_code = second_child[0]
	if second_child_code != symbol.trailer:
		return None
	if len(second_child) < 3:
		return None
	if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
		return fn_name
	else:
		return None
	return None

def find_fn_call(ast_list, calls):
	code = ast_list[0]
	if code == symbol.power:
		fn_name = get_fn_call_data(ast_list)
		if fn_name != None and getattr(__builtins__, fn_name, None) == None:
			calls.add(fn_name)

def process_fn(fn_ast_list, call_graph):
	dummy, dummy, func_name = fn_ast_list[:3]
	dummy, func_name = func_name
	calls = set()
	find_fn_call(fn_ast_list, calls)
	call_graph[func_name] = list(calls)

def construct_call_graph(ast_list, call_graph):
	code = ast_list[0]
	if code == symbol.funcdef:
		process_fn(ast_list, call_graph)

def generate_dot_code(python_code):
	ast = parser.suite(python_code)
	ast_list = parser.ast2list(ast)
	call_graph = {}
	construct_call_graph(ast_list, call_graph)
	dot = []
	dot.append('digraph G {')
	dot.append('rankdir=LR')

]:
	i: 0()
	o: 197(t), 333(f)

nname: 0
n 0(None)[__doc__ = '\ngenerates call graph of given python code file\nin dot format input for graphviz.\n\nlimitations:\n* statically tried to figure out functions calls\n* does not understand classes\n* algorithm is naive and may not statically find\n  all cases\n'
import sys
import parser
import symbol
import token
import pprint
import optparse
try:
	s = set()
]:
	i: 
	o: 94()

nname: 333
n 333(None)[]:
	i: 0(f)
	o: 

nname: 0
n 0(None)[__doc__ = '\ngenerates call graph of given python code file\nin dot format input for graphviz.\n\nlimitations:\n* statically tried to figure out functions calls\n* does not understand classes\n* algorithm is naive and may not statically find\n  all cases\n'
import sys
import parser
import symbol
import token
import pprint
import optparse
try:
	s = set()
except:
	import sets
	set = sets.Set
def annotate_ast_list(ast_list):
	code = ast_list[0]
	if code in symbol.sym_name:
		code = symbol.sym_name[code]
	else:
		code = token.tok_name[code]
	ast_list[0] = code

def get_atom_name(atom):
	first_child = atom[1]
	first_child_code = first_child[0]
	if first_child_code != token.NAME:
		return None
	return first_child[1]

def get_fn_call_data(ast_list):
	if len(ast_list) < 3:
		return None
	first_child, second_child = ast_list[1:3]
	first_child_code = first_child[0]
	if first_child_code != symbol.atom:
		return None
	fn_name = get_atom_name(first_child)
	second_child_code = second_child[0]
	if second_child_code != symbol.trailer:
		return None
	if len(second_child) < 3:
		return None
	if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
		return fn_name
	else:
		return None
	return None

def find_fn_call(ast_list, calls):
	code = ast_list[0]
	if code == symbol.power:
		fn_name = get_fn_call_data(ast_list)
		if fn_name != None and getattr(__builtins__, fn_name, None) == None:
			calls.add(fn_name)

def process_fn(fn_ast_list, call_graph):
	dummy, dummy, func_name = fn_ast_list[:3]
	dummy, func_name = func_name
	calls = set()
	find_fn_call(fn_ast_list, calls)
	call_graph[func_name] = list(calls)

def construct_call_graph(ast_list, call_graph):
	code = ast_list[0]
	if code == symbol.funcdef:
		process_fn(ast_list, call_graph)

def generate_dot_code(python_code):
	ast = parser.suite(python_code)
	ast_list = parser.ast2list(ast)
	call_graph = {}
	construct_call_graph(ast_list, call_graph)
	dot = []
	dot.append('digraph G {')
	dot.append('rankdir=LR')

if __name__ == '__main__':
	oparser = optparse.OptionParser()
	oparser.add_option('-i', '--input-file', default=None, metavar='FILE', help='python code file to process')
	options, args = oparser.parse_args()
	if options.input_file:
		python_code = open(options.input_file).read()
	else:
		python_code = sys.stdin.read()
	dot_code = generate_dot_code(python_code)
	print dot_code
]:
	i: 
	o: 333()

nname: 0
n 0(None)[__doc__ = '\ngenerates call graph of given python code file\nin dot format input for graphviz.\n\nlimitations:\n* statically tried to figure out functions calls\n* does not understand classes\n* algorithm is naive and may not statically find\n  all cases\n'
import sys
import parser
import symbol
import token
import pprint
import optparse
try:
	s = set()
except:
	import sets
	set = sets.Set
def annotate_ast_list(ast_list):
	code = ast_list[0]
	if code in symbol.sym_name:
		code = symbol.sym_name[code]
	else:
		code = token.tok_name[code]
	ast_list[0] = code

def get_atom_name(atom):
	first_child = atom[1]
	first_child_code = first_child[0]
	if first_child_code != token.NAME:
		return None
	return first_child[1]

def get_fn_call_data(ast_list):
	if len(ast_list) < 3:
		return None
	first_child, second_child = ast_list[1:3]
	first_child_code = first_child[0]
	if first_child_code != symbol.atom:
		return None
	fn_name = get_atom_name(first_child)
	second_child_code = second_child[0]
	if second_child_code != symbol.trailer:
		return None
	if len(second_child) < 3:
		return None
	if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
		return fn_name
	else:
		return None
	return None

def find_fn_call(ast_list, calls):
	code = ast_list[0]
	if code == symbol.power:
		fn_name = get_fn_call_data(ast_list)
		if fn_name != None and getattr(__builtins__, fn_name, None) == None:
			calls.add(fn_name)

def process_fn(fn_ast_list, call_graph):
	dummy, dummy, func_name = fn_ast_list[:3]
	dummy, func_name = func_name
	calls = set()
	find_fn_call(fn_ast_list, calls)
	call_graph[func_name] = list(calls)

def construct_call_graph(ast_list, call_graph):
	code = ast_list[0]
	if code == symbol.funcdef:
		process_fn(ast_list, call_graph)

def generate_dot_code(python_code):
	ast = parser.suite(python_code)
	ast_list = parser.ast2list(ast)
	call_graph = {}
	construct_call_graph(ast_list, call_graph)
	dot = []
	dot.append('digraph G {')
	dot.append('rankdir=LR')

if __name__ == '__main__':
	oparser = optparse.OptionParser()
	oparser.add_option('-i', '--input-file', default=None, metavar='FILE', help='python code file to process')
	options, args = oparser.parse_args()
	if options.input_file:
		python_code = open(options.input_file).read()
	else:
		python_code = sys.stdin.read()
	dot_code = generate_dot_code(python_code)
	print dot_code
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xb76049ac>}
__doc__ = '\ngenerates call graph of given python code file\nin dot format input for graphviz.\n\nlimitations:\n* statically tried to figure out functions calls\n* does not understand classes\n* algorithm is naive and may not statically find\n  all cases\n'
import sys
import parser
import symbol
import token
import pprint
import optparse
try:
	s = set()
except:
	import sets
	set = sets.Set
def annotate_ast_list(ast_list):
	code = ast_list[0]
	if code in symbol.sym_name:
		code = symbol.sym_name[code]
	else:
		code = token.tok_name[code]
	ast_list[0] = code

def get_atom_name(atom):
	first_child = atom[1]
	first_child_code = first_child[0]
	if first_child_code != token.NAME:
		return None
	return first_child[1]

def get_fn_call_data(ast_list):
	if len(ast_list) < 3:
		return None
	first_child, second_child = ast_list[1:3]
	first_child_code = first_child[0]
	if first_child_code != symbol.atom:
		return None
	fn_name = get_atom_name(first_child)
	second_child_code = second_child[0]
	if second_child_code != symbol.trailer:
		return None
	if len(second_child) < 3:
		return None
	if second_child[1][0] == token.LPAR and second_child[-1][0] == token.RPAR:
		return fn_name
	else:
		return None
	return None

def find_fn_call(ast_list, calls):
	code = ast_list[0]
	if code == symbol.power:
		fn_name = get_fn_call_data(ast_list)
		if fn_name != None and getattr(__builtins__, fn_name, None) == None:
			calls.add(fn_name)

def process_fn(fn_ast_list, call_graph):
	dummy, dummy, func_name = fn_ast_list[:3]
	dummy, func_name = func_name
	calls = set()
	find_fn_call(fn_ast_list, calls)
	call_graph[func_name] = list(calls)

def construct_call_graph(ast_list, call_graph):
	code = ast_list[0]
	if code == symbol.funcdef:
		process_fn(ast_list, call_graph)

def generate_dot_code(python_code):
	ast = parser.suite(python_code)
	ast_list = parser.ast2list(ast)
	call_graph = {}
	construct_call_graph(ast_list, call_graph)
	dot = []
	dot.append('digraph G {')
	dot.append('rankdir=LR')

if __name__ == '__main__':
	oparser = optparse.OptionParser()
	oparser.add_option('-i', '--input-file', default=None, metavar='FILE', help='python code file to process')
	options, args = oparser.parse_args()
	if options.input_file:
		python_code = open(options.input_file).read()
	else:
		python_code = sys.stdin.read()
	dot_code = generate_dot_code(python_code)
	print dot_code
